SatRdays London 2024
2024-04-27
みらい / mI ˈ ra ˈ i: /
But what’s so special about this? …
nanonextNanomsg Next Generation
Implementation completely devoid of polling loops:
Even for promises1
A world first!!
Special thanks to Joe Cheng (CTO Posit), creator of the Shiny framework
Instead uses: asynchronous callbacks from NNG
~500 lines of code (in total)
Minimal interface (good defaults)
No ‘intimidating’ array of options
Easy to pick up
environment() (the calling environment)crew extends mirai to High-Performance Computing environments such as traditional clusters or the cloudtargets reproducible pipeline ecosystem by Will LandauRequest by R Core (Luke Tierney) at R Project Sprint 2023
mirai added as the first alternative communications backend for the base parallel package.In 2017-2018, async programming introduced to R, and then Shiny, through the later and promises packages by Joe Cheng
library(shiny)
library(bslib)
library(mirai)
ui <- page_fluid(
numericInput("n", "Sample size (n)", 100),
numericInput("delay", "Seconds to take for plot", 5),
input_task_button("btn", "Plot uniform distribution"),
plotOutput("plot")
)
server <- function(input, output, session) {
extended_task <- ExtendedTask$new(
function(...) mirai({Sys.sleep(y); runif(x)}, ...)
) |> bind_task_button("btn")
observeEvent(input$btn, extended_task$invoke(x = input$n, y = input$delay))
output$plot <- renderPlot(hist(extended_task$result()))
}
app <- shinyApp(ui = ui, server = server)
with(daemons(2), runApp(app))bslib::input_task_button(). Nicer button automatically disabled during computation to prevent extra clicksExtendedTask$new() on a function passing ... to a mirai() call, bind it to the button created above...)library(shiny)
library(bslib)
library(mirai)
ui <- page_fluid(
numericInput("n", "Sample size (n)", 100),
numericInput("delay", "Seconds to take for plot", 5),
input_task_button("btn", "Plot uniform distribution"),
plotOutput("plot")
)
server <- function(input, output, session) {
extended_task <- ExtendedTask$new(
function(x, y) mirai({Sys.sleep(y); runif(x)}, environment())
) |> bind_task_button("btn")
observeEvent(input$btn, extended_task$invoke(input$n, input$delay))
output$plot <- renderPlot(hist(extended_task$result()))
}
app <- shinyApp(ui = ui, server = server)
with(daemons(2), runApp(app))library(plumber)
library(promises)
library(mirai)
pr() |>
pr_get(
"/echo",
function(req, res) {
mirai(
{ Sys.sleep(1L); list(status = 200L, body = list(msg = msg)) },
msg = req[["HEADERS"]][["msg"]]
) %...>% (function(x) {
res$status <- x$status
res$body <- x$body
})
}
) |>
pr_run(host = "127.0.0.1", port = 8985)function(req, res) {
mirai(
{
Sys.sleep(1L); list(status = 200L, body = list(msg = msg))
},
msg = req[["HEADERS"]][["msg"]]
) %...>% (function(x)
{
res$status <- x$status
res$body <- x$body
})
}General solution:
parallel packageThank you!
mirai package repository at https://github.com/shikokuchuo/mirai